package com.ruoyi.common.core.condition

/**
 * simple or表达
 * 仅支持like/in/equal
 * 仅支持单表
 * 不支持join、alias
 *
 * todo 因为ruoyi-common没有kotlin编译，先写这里，懒
 */
class Ors private constructor() {
    private val ors = mutableListOf<String>()

    companion object {
        fun builder() = Ors()
    }

    fun like(field: String, keyword: String): Ors {
        ors.add("$field like '%${keyword}%'")
        return this
    }

    fun like(field: String, keyword: Number): Ors {
        ors.add("$field like '%${keyword}%'")
        return this
    }

    fun like(fields: List<String>, keyword: String): Ors {
        fields.forEach { like(it, keyword) }
        return this
    }

    fun like(fields: List<String>, keyword: Number): Ors {
        fields.forEach { like(it, keyword) }
        return this
    }

    fun equal(field: String, value: String): Ors {
        ors.add("$field = '${value}'")
        return this
    }

    fun equal(field: String, value: Number): Ors {
        ors.add("$field = $value")
        return this
    }

    fun equal(fields: List<String>, value: String): Ors {
        fields.forEach { equal(it, value) }
        return this
    }

    fun equal(fields: List<String>, value: Number): Ors {
        fields.forEach { equal(it, value) }
        return this
    }

    // in，因为in是kotlin的关键字，只能用ins
    fun ins(field: String, values: Set<String>): Ors {
        if (values.isEmpty())
            return this

        val inValues = values.joinToString(prefix = "(", postfix = ")") { "'${it}'" }
        ors.add("$field in $inValues")
        return this
    }

    fun ins(fields: List<String>, values: Set<String>): Ors {
        fields.forEach { ins(it, values) }
        return this
    }

    // in，因为in是kotlin的关键字，只能用ins
    // 在java层调用，得使用ind
    @JvmName("ind")
    fun ins(field: String, values: Set<Number>): Ors {
        if (values.isEmpty())
            return this

        val inValues = values.joinToString(prefix = "(", postfix = ")")
        ors.add("$field in $inValues")
        return this
    }

    @JvmName("ind")
    fun ins(fields: List<String>, values: Set<Number>): Ors {
        fields.forEach { ins(it, values) }
        return this
    }

    fun build(): String = ors.joinToString(prefix = "(", postfix = ")", separator = " or ")
}

fun main() {
    val ors = Ors.builder()
        .equal("a", 132)
        .equal("b", "ddfdaf")
        .ins("label_code", setOf("1323", "323"))
        .ins("id", setOf(1, 2, 3))
        .ins("value", setOf(1.2, 2, 3))
        .like("name", "2322")
        .like("name", 213)
        .ins(listOf("aa", "bb", "cc"), setOf(32, 32))
        .build()
    print(ors)

    print(Ors.builder().build())
}